import { useEffect, useRef } from 'react'
import * as THREE from 'three'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

export const ThreeModel = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null)
  const controlsRef = useRef<OrbitControls | null>(null)

  useEffect(() => {
    if (!canvasRef.current) return

    const parent = canvasRef.current.parentElement
    if (!parent) return

    // 初始化场景、相机、渲染器
    const scene = new THREE.Scene()
    const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000)
    const renderer = new THREE.WebGLRenderer({
      canvas: canvasRef.current,
      alpha: true
    })
    renderer.setClearColor(0x000000, 0)

    // 初始化轨道控制器
    const controls = new OrbitControls(camera, renderer.domElement)
    controlsRef.current = controls
    controls.enableDamping = true // 启用阻尼效果
    controls.dampingFactor = 0.05 // 阻尼系数
    controls.rotateSpeed = 0.5 // 旋转速度
    controls.zoomSpeed = 0.8 // 缩放速度
    controls.panSpeed = 0.5 // 平移速度

    // 添加光源
    const ambientLight = new THREE.AmbientLight(0xffffff, 2)
    scene.add(ambientLight)

    const directionalLight = new THREE.DirectionalLight(0xffffff, 6)
    directionalLight.position.set(1, 1, 0.5).normalize()
    scene.add(directionalLight)

    // 加载模型
    const loader = new GLTFLoader()
    loader.load('/models/Animated.gltf', (gltf) => {
      gltf.scene.scale.set(2.5, 2.5, 2.5)

      // 模型居中
      const box = new THREE.Box3().setFromObject(gltf.scene)
      const center = box.getCenter(new THREE.Vector3())
      gltf.scene.position.sub(center)

      scene.add(gltf.scene)

      // 设置控制器目标
      controls.target.copy(gltf.scene.position)
      controls.update()

      // 初始相机位置
      camera.position.set(0, 0.5, 2)
      camera.lookAt(gltf.scene.position)
    })

    // 动画循环
    const animate = () => {
      requestAnimationFrame(animate)
      controls.update() // 需要更新控制器
      renderer.render(scene, camera)
    }

    // 响应式处理
    const resizeObserver = new ResizeObserver((entries) => {
      const { width, height } = entries[0].contentRect
      camera.aspect = width / height
      camera.updateProjectionMatrix()
      renderer.setSize(width, height)
    })
    resizeObserver.observe(parent)

    animate()

    // 清理函数
    return () => {
      resizeObserver.disconnect()
      controls.dispose()
      renderer.dispose()
    }
  }, [])

  return <canvas ref={canvasRef} style={{ width: '100%', height: '100%' }} />
}
